from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from fastapi.staticfiles import StaticFiles
from starlette.exceptions import HTTPException as StarletteHTTPException
import logging
import time
from pathlib import Path
from .core.config import settings
from .api.v1.api import api_router

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI):
    # 启动事件
    logger.info("Echo Role 后端服务启动成功")
    logger.info(f"服务运行在: http://localhost:{settings.PORT}")
    yield
    # 关闭事件
    logger.info("Echo Role 后端服务关闭")


def create_app() -> FastAPI:
    
    app = FastAPI(
        title=settings.PROJECT_NAME,
        description="Echo Role AI语音聊天平台后端API",
        version="1.0.0",
        openapi_url=(
            f"{settings.API_V1_STR}/openapi.json" 
            if settings.DEBUG else None
        ),
        docs_url="/docs" if settings.DEBUG else None,
        redoc_url="/redoc" if settings.DEBUG else None,
        lifespan=lifespan
    )
    
    # 添加CORS中间件
    app.add_middleware(
        CORSMiddleware,
        allow_origins=settings.BACKEND_CORS_ORIGINS,
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
    
    # 添加可信任主机中间件
    if not settings.DEBUG:
        allowed_hosts = (
            ["localhost", "127.0.0.1", "0.0.0.0"] + 
            settings.BACKEND_CORS_ORIGINS
        )
        app.add_middleware(
            TrustedHostMiddleware,
            allowed_hosts=allowed_hosts
        )
    
    # 添加请求处理时间中间件
    @app.middleware("http")
    async def add_process_time_header(request: Request, call_next):
        start_time = time.time()
        response = await call_next(request)
        process_time = time.time() - start_time
        response.headers["X-Process-Time"] = str(process_time)
        return response
    
    # 全局异常处理
    @app.exception_handler(StarletteHTTPException)
    async def http_exception_handler(
        request: Request, exc: StarletteHTTPException
    ):
        return JSONResponse(
            status_code=exc.status_code,
            content={
                "code": exc.status_code,
                "message": exc.detail,
                "data": None
            },
            media_type="application/json; charset=utf-8"
        )
    
    @app.exception_handler(RequestValidationError)
    async def validation_exception_handler(
        request: Request, exc: RequestValidationError
    ):
        return JSONResponse(
            status_code=422,
            content={
                "code": 422,
                "message": "请求参数验证失败",
                "data": {
                    "errors": exc.errors()
                }
            },
            media_type="application/json; charset=utf-8"
        )

    # 健康检查端点
    @app.get("/health")
    async def health_check():
        return {
            "code": 200,
            "message": "服务运行正常",
            "data": {
                "status": "healthy",
                "version": "1.0.0"
            }
        }
    
    # 创建静态文件目录
    static_dir = Path(settings.STATIC_DIR)
    static_dir.mkdir(parents=True, exist_ok=True)
    audio_dir = static_dir / "audio"
    audio_dir.mkdir(parents=True, exist_ok=True)
    
    # 挂载静态文件服务
    app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
    
    # 包含API路由
    app.include_router(api_router, prefix=settings.API_V1_STR)
    
    return app


# 创建应用实例
app = create_app()


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "app.main:app",
        host="0.0.0.0",
        port=settings.PORT,
        reload=settings.DEBUG,
        log_level="info"
    )